`include "../src/alu.v"
`timescale  1ns / 1ps

module tb_alu;
  // alu Parameters
  parameter PERIOD  = 100;

  // alu Inputs
  reg   [31:0]  alu_in1   = 0;
  reg   [31:0]  alu_in2   = 0;
  reg   [3:0]  alu_op_ctr = 0;

  // alu Outputs
  wire  [31:0]  alu_result;
  wire  zero;

  initial begin
    #PERIOD
    alu_op_ctr  = `ALU_AND;
    alu_in1     = 32'hABCD1234;
    alu_in2     = 32'hBCDE2345;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/2)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
    #PERIOD
    alu_op_ctr  = `ALU_OR;
    alu_in1     = 32'hCDEF3456;
    alu_in2     = 32'hACDE4567;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/5)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
    #PERIOD
    alu_op_ctr  = `ALU_ADD;
    alu_in1     = 32'hABCD1234;
    alu_in2     = 32'hBCDE2345;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/5)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
    #PERIOD
    alu_op_ctr  = `ALU_SUB;
    alu_in1     = 32'hCDEF3456;
    alu_in2     = 32'hACDE4567;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/5)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
    #PERIOD
    alu_op_ctr  = `ALU_NOP;
    alu_in1     = 32'hABCD1234;
    alu_in2     = 32'hBCDE2345;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/5)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
    #PERIOD
    alu_op_ctr  = `ALU_SUB;
    alu_in1     = 32'hABCD1234;
    alu_in2     = 32'hABCD1234;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/5)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
    #PERIOD
    alu_op_ctr  = `ALU_ADD;
    alu_in1     = 32'hABCD1234;
    alu_in2     = -alu_in1;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/5)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
    #PERIOD
    alu_op_ctr  = `ALU_NOP;
    alu_in1     = 32'hABCD1234;
    alu_in2     = 32'hBCDE2345;
    $display("and: %4b", alu_op_ctr);
    $display("and: \t%32d \t%32x \t%32b", alu_in1, alu_in1, alu_in1);
    $display("and: \t%32d \t%32x \t%32b", alu_in2, alu_in2, alu_in2);
    #(PERIOD/5)
    $display("and: \t%32d \t%32x \t%32b", alu_result, alu_result, alu_result);
  end

  alu u_alu (
    .alu_in1(alu_in1[31:0]),
    .alu_in2(alu_in2[31:0]),
    .alu_op_ctr( alu_op_ctr[3:0]),
    
    .alu_result(alu_result[31:0]),
    .zero(zero)
  );


  /*iverilog */
  initial
  begin            
    $dumpfile("tb_alu.vcd");  //生成的vcd文件名称
    $dumpvars(0, tb_alu);       //tb模块名称
  end
  /*iverilog */

endmodule
